package com.zhongying.jf.util.vaild;

import com.zhongying.jf.Constant;
import com.zhongying.jf.exception.ZhongyingiException;
import com.zhongying.jf.ResConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: liuhao
 */
@Component
public class ApiInterfaceVaild {



    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };


    public boolean checkPublicParamters(HttpServletRequest httpServletRequest) {

        checkSign(httpServletRequest); //数字签名的验证
        return true;
    }


    /**
     * 检查数字签名是否正确
     * @param httpServletRequest
     */
    public static void checkSign(HttpServletRequest httpServletRequest) {
        String sign = httpServletRequest.getParameter("sign");//客户端的数字签名
        String secret = httpServletRequest.getParameter("secret");
        if(!Constant.secret.equals(secret))
            throw new ZhongyingiException(ResConstants.PARAM_NOT_RIGHT.getCode() , "非指定商户");

        if(StringUtils.isNotBlank(sign) && StringUtils.isNotBlank(secret)) {
            Map<String,String[]> params = httpServletRequest.getParameterMap();
            Map<String,String> newMap = cloneNewMap(params);

/*            String[] keyArray = newMap.keySet().toArray(new String[0]);
            Arrays.sort(keyArray);
            StringBuilder sb = new StringBuilder();
            for(String key : keyArray) {
                sb.append(key).append(newMap.get(key));
                System.out.println(key+"="+newMap.get(key));
                System.out.println(sb);
            }*/
//            sb.append(secret);
            //String signencode = org.apache.commons.codec.digest.DigestUtils.shaHex(sb.toString()).toUpperCase();  //服务台解析后的数字签名

            String signencode = sign(secret,newMap);
            System.out.println("客户端="+sign+"服务端="+signencode);
            if(!signencode.equals(sign))
                throw new ZhongyingiException(ResConstants.DIGITAL_SIGN_EXCEPTION.getCode(),"数字签名不一致，请重新确认接口的参数正确性！");
        } else {
            throw new ZhongyingiException(ResConstants.DIGITAL_SIGN_EXCEPTION.getCode(),"数字签名为空");
        }

    }

    private static Map<String,String> cloneNewMap(Map<String,String[]> paramsMap){
        Map<String,String> newMap = new HashMap<>();
        Iterator<Map.Entry<String, String[]>> iterator = paramsMap.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String, String[]> entry = iterator.next();
            String key = entry.getKey();
            if(!key.equals("sign") && !key.equals("secret")){
                newMap.put(key,entry.getValue()[0]);
            }
        }
        return newMap;
    }



    private static String sign(String secret, Map<String, String> paramMap) {

        // 参数名排序
        String[] keyArray = paramMap.keySet().toArray(new String[0]);
        Arrays.sort(keyArray);

        // 拼接参数
        StringBuilder stringBuilder = new StringBuilder();
        //stringBuilder.append(appKey);
        for (String key : keyArray)
        {
            try {
                String value = paramMap.get(key);
/*                if (!TextUtils.isEmpty(value)) {
                    stringBuilder.append(key).append(URLEncoder.encode(value, "UTF-8"));
                }
                else {
                    stringBuilder.append(key).append(value);
                }*/
                stringBuilder.append(key).append(value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        System.out.println(stringBuilder.toString());
        stringBuilder.append(secret);
        String codes = stringBuilder.toString();
        System.out.println(codes);
        // SHA-1签名
        // For Android
        //String sign = new String(Hex.encodeHex(DigestUtils.sha(codes))).toUpperCase();
        String sign = null;
        try {
            sign = SHA1(codes).toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return sign;
    }

    private  static String convertToHex(byte[] data) {

        int len = data.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(data[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[data[j] & 0x0f]);
        }
        return buf.toString();

    }

    private static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {

        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] sha1hash = new byte[40];
        md.update(text.getBytes("utf-8"), 0, text.length());
        sha1hash = md.digest();

        return convertToHex(sha1hash);

    }
}
